🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / core / network / src / commonTest / kotlin / org / meshtastic / core / network / radio / TcpRadioTransportTest.kt
Displaying Raw • Download
core/network/src/commonTest/kotlin/org/meshtastic/core/network/radio/TcpRadioTransportTest.kt 65a1f5ce4d0e4b8eafcd0bbfccafd41dc6ee888a (65a1f5ce) Text, 10.89 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.network.radio
Tff7b72import T7ee787dev.mokkery.MockMode
Tff7b72import T7ee787dev.mokkery.mock
Tff7b72import T7ee787kotlinx.atomicfu.atomic
Tff7b72import T7ee787kotlinx.atomicfu.locks.SynchronizedObject
Tff7b72import T7ee787kotlinx.atomicfu.locks.synchronized
Tff7b72import T7ee787kotlinx.coroutines.CompletableDeferred
Tff7b72import T7ee787kotlinx.coroutines.CoroutineScope
Tff7b72import T7ee787kotlinx.coroutines.CoroutineStart
Tff7b72import T7ee787kotlinx.coroutines.Dispatchers
Tff7b72import T7ee787kotlinx.coroutines.SupervisorJob
Tff7b72import T7ee787kotlinx.coroutines.async
Tff7b72import T7ee787kotlinx.coroutines.cancel
Tff7b72import T7ee787kotlinx.coroutines.runBlocking
Tff7b72import T7ee787kotlinx.coroutines.test.StandardTestDispatcher
Tff7b72import T7ee787kotlinx.coroutines.test.advanceTimeBy
Tff7b72import T7ee787kotlinx.coroutines.test.runCurrent
Tff7b72import T7ee787kotlinx.coroutines.test.runTest
Tff7b72import T7ee787kotlinx.coroutines.withContext
Tff7b72import T7ee787kotlinx.coroutines.withTimeout
Tff7b72import T7ee787kotlinx.coroutines.withTimeoutOrNull
Tff7b72import T7ee787org.meshtastic.core.di.CoroutineDispatchers
Tff7b72import T7ee787org.meshtastic.core.network.transport.TcpTransport
Tff7b72import T7ee787org.meshtastic.core.repository.RadioTransportCallback
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertFalse
Tff7b72import T7ee787kotlin.test.assertNull
Tff7b72import T7ee787kotlin.test.assertTrue
Tff7b72import T7ee787kotlin.time.Duration.Companion.milliseconds
Tff7b72import T7ee787kotlin.time.Duration.Companion.seconds
Tff7b72class T56d364TcpRadioTransportTest Tb4b4b4{
Tff7b72private Tff7b72val Te6edf3callbackTb4b4b4: Te6edf3RadioTransportCallback Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72class T56d364FakeTcpRadioConnection Tb4b4b4: Te6edf3TcpRadioConnection Tb4b4b4{
Tff7b72private Tff7b72val Te6edf3connectedState Tff7b72= Te6edf3atomicTb4b4b4(Tff7b72falseTb4b4b4)
Tff7b72var Te6edf3connectedTb4b4b4: Tffa657Boolean
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3connectedStateTb4b4b4.Te6edf3value
Tff7b72setTb4b4b4(Te6edf3valueTb4b4b4) Tb4b4b4{
Te6edf3connectedStateTb4b4b4.Te6edf3value Tff7b72= Te6edf3value
Tb4b4b4}
Tff7b72private Tff7b72val Te6edf3sentPacketsLock Tff7b72= Te6edf3SynchronizedObjectTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3mutableSentPackets Tff7b72= Te6edf3mutableListOfTff7b72<Te6edf3ByteArrayTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3startsState Tff7b72= Te6edf3atomicTb4b4b4(T79c0ff0Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3stopsState Tff7b72= Te6edf3atomicTb4b4b4(T79c0ff0Tb4b4b4)
Tff7b72val Te6edf3sentPacketsTb4b4b4: Te6edf3ListTff7b72<Te6edf3ByteArrayTff7b72>
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3synchronizedTb4b4b4(Te6edf3sentPacketsLockTb4b4b4) Tb4b4b4{ Te6edf3mutableSentPacketsTb4b4b4.Te6edf3toListTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72val Te6edf3startsTb4b4b4: Tffa657Int
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3startsStateTb4b4b4.Te6edf3value
Tff7b72val Te6edf3stopsTb4b4b4: Tffa657Int
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3stopsStateTb4b4b4.Te6edf3value
Tff7b72var Te6edf3stopStartedTb4b4b4: Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tff7b72? Tff7b72= Tff7b72null
Tff7b72var Te6edf3releaseStopTb4b4b4: Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tff7b72? Tff7b72= Tff7b72null
Tff7b72var Te6edf3sendStartedTb4b4b4: Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tff7b72? Tff7b72= Tff7b72null
Tff7b72var Te6edf3releaseSendTb4b4b4: Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tff7b72? Tff7b72= Tff7b72null
Tff7b72private Tff7b72val Te6edf3sendInFlight Tff7b72= Te6edf3atomicTb4b4b4(Tff7b72falseTb4b4b4)
Tff7b72private Tff7b72val Te6edf3stopObservedSendInFlightState Tff7b72= Te6edf3atomicTb4b4b4(Tff7b72falseTb4b4b4)
Tff7b72val Te6edf3stopObservedSendInFlightTb4b4b4: Tffa657Boolean
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3stopObservedSendInFlightStateTb4b4b4.Te6edf3value
Tff7b72override Tff7b72val Te6edf3isConnectedTb4b4b4: Tffa657Boolean
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3connected
Tff7b72override Tff7b72fun Td2a8ffstartTb4b4b4(Te6edf3addressTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Te6edf3startsStateTb4b4b4.Te6edf3incrementAndGetTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tff7b72override Tff7b72fun Td2a8ffstopTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3stopsStateTb4b4b4.Te6edf3incrementAndGetTb4b4b4(Tb4b4b4)
Te6edf3stopObservedSendInFlightStateTb4b4b4.Te6edf3value Tff7b72= Te6edf3sendInFlightTb4b4b4.Te6edf3value
Te6edf3stopStartedTff7b72?.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3releaseStopTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3gate Tff7b72-Tff7b72> Te6edf3runBlocking Tb4b4b4{ Te6edf3withTimeoutTb4b4b4(T79c0ff5.Te6edf3secondsTb4b4b4) Tb4b4b4{ Te6edf3gateTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4) Tb4b4b4} Tb4b4b4} Tb4b4b4}
Te6edf3connected Tff7b72= Tff7b72false
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsendPacketTb4b4b4(Te6edf3payloadTb4b4b4: Te6edf3ByteArrayTb4b4b4) Tb4b4b4{
Te6edf3sendInFlightTb4b4b4.Te6edf3value Tff7b72= Tff7b72true
Tff7b72try Tb4b4b4{
Te6edf3sendStartedTff7b72?.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3releaseSendTff7b72?.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3synchronizedTb4b4b4(Te6edf3sentPacketsLockTb4b4b4) Tb4b4b4{ Te6edf3mutableSentPackets Tff7b72+Tff7b72= Te6edf3payload Tb4b4b4}
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3sendInFlightTb4b4b4.Te6edf3value Tff7b72= Tff7b72false
Tb4b4b4}
Tb4b4b4}
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffsendHeartbeatTb4b4b4(Tb4b4b4) Tff7b72= Tffa657Unit
Tb4b4b4}
Tff7b72private Tff7b72fun Td2a8ffcreateTransportTb4b4b4(Te6edf3scopeTb4b4b4: Te6edf3CoroutineScopeTb4b4b4, Te6edf3connectionTb4b4b4: Te6edf3FakeTcpRadioConnectionTb4b4b4)Tb4b4b4: Te6edf3TcpRadioTransport Tff7b72=
Te6edf3TcpRadioTransportTb4b4b4(
Te6edf3callback Tff7b72= Te6edf3callbackTb4b4b4,
Te6edf3scope Tff7b72= Te6edf3scopeTb4b4b4,
Te6edf3address Tff7b72= Ta5d6ff"Ta5d6ff127.0.0.1Ta5d6ff"Tb4b4b4,
Te6edf3connectionFactory Tff7b72= Tb4b4b4{ Te6edf3_Tb4b4b4: Te6edf3TcpTransportTb4b4b4.Te6edf3Listener Tff7b72-Tff7b72> Te6edf3connection Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tf0883e@Test
Tff7b72fun Td2a8ff`send is rejected while the transport was never started`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3dispatcher Tff7b72= Te6edf3StandardTestDispatcherTb4b4b4(Te6edf3testSchedulerTb4b4b4)
Tff7b72val Te6edf3dispatchers Tff7b72= Te6edf3CoroutineDispatchersTb4b4b4(Te6edf3io Tff7b72= Te6edf3dispatcherTb4b4b4, Te6edf3main Tff7b72= Te6edf3dispatcherTb4b4b4, Te6edf3default Tff7b72= Te6edf3dispatcherTb4b4b4)
Tff7b72val Te6edf3transport Tff7b72= Te6edf3TcpRadioTransportTb4b4b4(Te6edf3callbackTb4b4b4, Tff7b72thisTb4b4b4, Te6edf3dispatchersTb4b4b4, Te6edf3address Tff7b72= Ta5d6ff"Ta5d6ff127.0.0.1Ta5d6ff"Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff4Tb4b4b4, T79c0ff5Tb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`established transport admits send before close and rejects after close`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3connection Tff7b72= Te6edf3FakeTcpRadioConnectionTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{ Te6edf3connected Tff7b72= Tff7b72true Tb4b4b4}
Tff7b72val Te6edf3transport Tff7b72= Te6edf3createTransportTb4b4b4(Tff7b72thisTb4b4b4, Te6edf3connectionTb4b4b4)
Tff7b72val Te6edf3payload Tff7b72= Te6edf3byteArrayOfTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4, T79c0ff3Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3payloadTb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3payloadTb4b4b4.Te6edf3toListTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4, Te6edf3connectionTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3mapTb4b4b4(Te6edf3ByteArrayTff7b72::Te6edf3toListTb4b4b4)Tb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff4Tb4b4b4, T79c0ff5Tb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3connectionTb4b4b4.Te6edf3stopsTb4b4b4)
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`close waits for an admitted send to finish before stopping the connection`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3payload Tff7b72= Te6edf3byteArrayOfTb4b4b4(T79c0ff4Tb4b4b4, T79c0ff5Tb4b4b4, T79c0ff6Tb4b4b4)
Tff7b72val Te6edf3sendStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3releaseSend Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3stopStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3connection Tff7b72=
Te6edf3FakeTcpRadioConnectionTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3connected Tff7b72= Tff7b72true
Tff7b72thisTb4b4b4.Te6edf3sendStarted Tff7b72= Te6edf3sendStarted
Tff7b72thisTb4b4b4.Te6edf3releaseSend Tff7b72= Te6edf3releaseSend
Tff7b72thisTb4b4b4.Te6edf3stopStarted Tff7b72= Te6edf3stopStarted
Tb4b4b4}
Tff7b72val Te6edf3transportScope Tff7b72= Te6edf3CoroutineScopeTb4b4b4(Te6edf3SupervisorJobTb4b4b4(Tb4b4b4) Tff7b72+ Te6edf3DispatchersTb4b4b4.Te6edf3DefaultTb4b4b4)
Tff7b72val Te6edf3transport Tff7b72= Te6edf3createTransportTb4b4b4(Te6edf3transportScopeTb4b4b4, Te6edf3connectionTb4b4b4)
Tff7b72try Tb4b4b4{
Te6edf3assertTrueTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3payloadTb4b4b4)Tb4b4b4)
Te6edf3sendStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3closeJob Tff7b72= Te6edf3asyncTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3DefaultTb4b4b4, Te6edf3start Tff7b72= Te6edf3CoroutineStartTb4b4b4.Te6edf3UNDISPATCHEDTb4b4b4) Tb4b4b4{ Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72val Te6edf3prematureStop Tff7b72=
Te6edf3withContextTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3DefaultTb4b4b4) Tb4b4b4{ Te6edf3withTimeoutOrNullTb4b4b4(T79c0ff2T79c0ff0T79c0ff0.Te6edf3millisecondsTb4b4b4) Tb4b4b4{ Te6edf3stopStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4) Tb4b4b4} Tb4b4b4}
Te6edf3assertNullTb4b4b4(Te6edf3prematureStopTb4b4b4, Ta5d6ff"Ta5d6ffclose must not stop the connection while admitted TCP I/O is suspendedTa5d6ff"Tb4b4b4)
Te6edf3releaseSendTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3withContextTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3DefaultTb4b4b4) Tb4b4b4{ Te6edf3withTimeoutTb4b4b4(T79c0ff5.Te6edf3secondsTb4b4b4) Tb4b4b4{ Te6edf3stopStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4) Tb4b4b4} Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(
Te6edf3listOfTb4b4b4(Te6edf3payloadTb4b4b4.Te6edf3toListTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3connectionTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3mapTb4b4b4(Te6edf3ByteArrayTff7b72::Te6edf3toListTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffthe admitted send must finish before connection teardown startsTa5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3connectionTb4b4b4.Te6edf3stopObservedSendInFlightTb4b4b4)
Te6edf3closeJobTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3connectionTb4b4b4.Te6edf3stopsTb4b4b4)
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3releaseSendTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)
Te6edf3transportScopeTb4b4b4.Te6edf3cancelTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`hung admitted send times out before close stops the connection`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sendStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3releaseSend Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3connection Tff7b72=
Te6edf3FakeTcpRadioConnectionTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3connected Tff7b72= Tff7b72true
Tff7b72thisTb4b4b4.Te6edf3sendStarted Tff7b72= Te6edf3sendStarted
Tff7b72thisTb4b4b4.Te6edf3releaseSend Tff7b72= Te6edf3releaseSend
Tb4b4b4}
Tff7b72val Te6edf3transport Tff7b72= Te6edf3createTransportTb4b4b4(Tff7b72thisTb4b4b4, Te6edf3connectionTb4b4b4)
Tff7b72try Tb4b4b4{
Te6edf3assertTrueTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3sendStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3closeJob Tff7b72= Te6edf3async Tb4b4b4{ Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4) Tb4b4b4}
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3advanceTimeByTb4b4b4(Te6edf3TcpRadioTransportTb4b4b4.Te6edf3OPERATION_TIMEOUTTb4b4b4.Te6edf3inWholeMillisecondsTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3closeJobTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3connectionTb4b4b4.Te6edf3stopsTb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3connectionTb4b4b4.Te6edf3stopObservedSendInFlightTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3connectionTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3releaseSendTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`operation timeout stops a connection before another send can be admitted`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3sendStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3releaseSend Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3connection Tff7b72=
Te6edf3FakeTcpRadioConnectionTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3connected Tff7b72= Tff7b72true
Tff7b72thisTb4b4b4.Te6edf3sendStarted Tff7b72= Te6edf3sendStarted
Tff7b72thisTb4b4b4.Te6edf3releaseSend Tff7b72= Te6edf3releaseSend
Tb4b4b4}
Tff7b72val Te6edf3transport Tff7b72= Te6edf3createTransportTb4b4b4(Tff7b72thisTb4b4b4, Te6edf3connectionTb4b4b4)
Tff7b72try Tb4b4b4{
Te6edf3transportTb4b4b4.Te6edf3startTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3connectionTb4b4b4.Te6edf3startsTb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff1Tb4b4b4, T79c0ff2Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3sendStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3advanceTimeByTb4b4b4(Te6edf3TcpRadioTransportTb4b4b4.Te6edf3OPERATION_TIMEOUTTb4b4b4.Te6edf3inWholeMillisecondsTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3connectionTb4b4b4.Te6edf3stopsTb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3startTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3connectionTb4b4b4.Te6edf3startsTb4b4b4, Ta5d6ff"Ta5d6ffa stopped TCP transport must not be restarted in placeTa5d6ff"Tb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff4Tb4b4b4, T79c0ff5Tb4b4b4, T79c0ff6Tb4b4b4)Tb4b4b4)Tb4b4b4)
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3releaseSendTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tf0883e@Test
Tff7b72fun Td2a8ff`close racing with send wins admission before teardown can return`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3stopStarted Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3releaseStop Tff7b72= Te6edf3CompletableDeferredTff7b72<Tffa657UnitTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3connection Tff7b72=
Te6edf3FakeTcpRadioConnectionTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3connected Tff7b72= Tff7b72true
Tff7b72thisTb4b4b4.Te6edf3stopStarted Tff7b72= Te6edf3stopStarted
Tff7b72thisTb4b4b4.Te6edf3releaseStop Tff7b72= Te6edf3releaseStop
Tb4b4b4}
Tff7b72val Te6edf3transport Tff7b72= Te6edf3createTransportTb4b4b4(Tff7b72thisTb4b4b4, Te6edf3connectionTb4b4b4)
T8b949e// Both close and send use real threads here: close blocks inside the fake stop callback while the second
T8b949e// Default worker verifies that lifecycle admission has already closed.
Tff7b72val Te6edf3closeJob Tff7b72= Te6edf3asyncTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3DefaultTb4b4b4) Tb4b4b4{ Te6edf3transportTb4b4b4.Te6edf3closeTb4b4b4(Tb4b4b4) Tb4b4b4}
Tff7b72try Tb4b4b4{
Te6edf3stopStartedTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3sendJob Tff7b72= Te6edf3asyncTb4b4b4(Te6edf3DispatchersTb4b4b4.Te6edf3DefaultTb4b4b4) Tb4b4b4{ Te6edf3transportTb4b4b4.Te6edf3handleSendToRadioTb4b4b4(Te6edf3byteArrayOfTb4b4b4(T79c0ff7Tb4b4b4, T79c0ff8Tb4b4b4, T79c0ff9Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3assertFalseTb4b4b4(Te6edf3sendJobTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffsend must be rejected while the first close is still drainingTa5d6ff"Tb4b4b4)
Tb4b4b4} Tff7b72finally Tb4b4b4{
Te6edf3releaseStopTb4b4b4.Te6edf3completeTb4b4b4(Tffa657UnitTb4b4b4)
Tb4b4b4}
Te6edf3closeJobTb4b4b4.Te6edf3awaitTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3connectionTb4b4b4.Te6edf3sentPacketsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.08s